// /*
//     sleep函数可以使计算机程序（进程 任务或线程）进入休眠，使其在一段时间内处于非活动状态， 
//     当函数设定的计时器到期 或者接收到信号程序发生中断都会导致程序继续执行


//     JS是单线程运行的，没有内部sleep函数，但是可以自己尝试封装
// */ 

// // 需求： 以下代码
function fnA() {
    console.log('A');
};

function fnB() {
    console.log('B');
};

function fnC() {
    console.log('C');
};

// // 实现目标
// fnA();  // 1秒打印
// fnB();  // 2秒打印
// fnC();  // 3秒打印


// /*
//     1. setTimeout函数封装
//         缺点： 不会阻塞同步任务，有时候sleep需要能够阻塞同步执行代码，这种方法就不能实现
// */
function sleep1(fn, delay) {
    setTimeout(() => {
        fn();  // 执行函数
    }, delay);
}; 

// sleep1(fnA, 1000);   // 1秒打印
// sleep1(fnB, 2000);   // 2秒打印
// sleep1(fnC, 3000);   // 3秒打印


// /*
//     2. Promise封装
//         缺点：实现了链式调用，但是仍然没有解决阻塞同步代码的问题
// */ 

function sleep2(time) {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve() 
        }, time);
    });
};

// sleep2(1000).then(fnA);  // 1秒打印
// sleep2(2000).then(fnB);  // 2秒打印
// sleep2(3000).then(fnC);  // 3秒打印


/*
    3. async await

*/
async function sleepTest() {
    fnA();
    await sleep2(1000);
    console.log('E');
    fnB();
    await sleep2(1000);
    console.log('F');
    fnC();
    await sleep2(1000);
    console.log('G')
};

sleepTest();    // A  E  B C G

// async await是promise语法糖
function sleepTest1() {
    fnA();
    return new Promise((resolve, reject) => {
        resolve();
        sleep2(1000);
    }).then(() => {
        console.log('E'); 
        fnB(); 
        return new Promise((resolve, reject) => {
            resolve();
            sleep2(1000);
        }).then(() => {
            console.log('F'); 
            fnC();
            return new Promise((resolve, reject) => {
                resolve();
                sleep2(1000);
            }).then(() => {
                console.log('G');
            })
        });
    });
};

sleepTest1();   // A E B F C G